import {AxdrType} from "../asn1.axdr/AxdrType";
import {ReverseByteArrayOutputStream} from "../ReverseByteArrayOutputStream";
import {Buffer} from "buffer";
import {Get_Request} from "./Get_Request";
import {AxdrEnum} from "../asn1.axdr/AxdrEnum";
import {ReverseByteArrayInputStream} from "../ReverseByteArrayInputStream";
import {Set_Request} from "./Set_Request";
import {Action_Request} from "./Action_Request";
import {Security_Request} from "./Security_Request";
import {Connect_Request} from "./Connect_Request";
import {Proxy_Request} from "./Proxy_Request";
import {Get_Response} from "./Get_Response";
import {Set_Response} from "./Set_Response";
import {Action_Response} from "./Action_Response";
import {Proxy_Response} from "./Proxy_Response";
import {Security_Response} from "./Security_Response";
import {Connect_Response} from "./Connect_Response";


export enum Choice {
    _ERR_NONE_SELECTED = -1,
    CONNECT_REQUEST = 2,
    GET_REQUEST = 5,
    SET_REQUEST = 6,
    ACTION_REQUEST = 7,
    PROXY_REQUEST = 9,
    SECURITY_REQUEST = 16,
    GET_RESPONSE = 133,
    SET_RESPONSE = 134,
    CONNECT_RESPONSE = 130,
    ACTION_RESPONSE = 135,
    PROXY_RESPONSE = 137,
    SECURITY_RESPONSE = 144,
}

export class M698pdu implements AxdrType {

    choice: Choice = Choice._ERR_NONE_SELECTED;

    dataCode: Buffer | null = null;

    get_request: Get_Request | null = null;

    set_request: Set_Request | null = null;

    action_request: Action_Request | null = null;

    security_request : Security_Request | null = null;

    connect_request : Connect_Request | null = null;

    proxy_request : Proxy_Request | null = null;

    get_response : Get_Response | null = null;

    set_response : Set_Response | null = null;

    action_response : Action_Response | null = null;

    proxy_response : Proxy_Response | null = null;

    security_response : Security_Response | null = null;

    connect_response : Connect_Response | null = null;

    static instance = null;

    static getInstance() : M698pdu{
        if(this.instance == null){
            this.instance = new M698pdu();
        }
        return this.instance;
    }

    constructor() {
    }

    set_dataCode(dataCode: Buffer){
        this.dataCode = dataCode;
    }

    decode(input: ReverseByteArrayInputStream): number {
        let codeLength = 0;
        let choosen = new AxdrEnum();
        choosen.set_const();

        codeLength += choosen.decode(input);
        this.resetChoices();
        this.choice = choosen.getValue();
        if (this.choice == Choice.GET_REQUEST) {
            this.get_request = new Get_Request();
            codeLength += this.get_request.decode(input);
            return codeLength;
        }else if(this.choice == Choice.SET_REQUEST){
            this.set_request = new Set_Request();
            codeLength += this.set_request.decode(input);
            return codeLength;
        }else if (this.choice == Choice.ACTION_REQUEST) {
            this.action_request = new Action_Request();
            codeLength += this.action_request.decode(input);
            return codeLength;
        }else if (this.choice == Choice.SECURITY_REQUEST) {
            this.security_request = new Security_Request();
            codeLength += this.security_request.decode(input);
            return codeLength;
        }else if(this.choice == Choice.CONNECT_REQUEST){
            this.connect_request = new Connect_Request();
            codeLength += this.connect_request.decode(input);
            return codeLength;
        }else if(this.choice == Choice.PROXY_REQUEST){
            this.proxy_request = new Proxy_Request();
            codeLength += this.proxy_request.decode(input);
            return codeLength;
        }else if (this.choice == Choice.GET_RESPONSE) {
            this.get_response = new Get_Response();
            codeLength += this.get_response.decode(input);
            return codeLength;
        }else if (this.choice == Choice.SET_RESPONSE) {
            this.set_response = new Set_Response();
            codeLength += this.set_response.decode(input);
            return codeLength;
        }else if (this.choice == Choice.ACTION_RESPONSE) {
            this.action_response = new Action_Response();
            codeLength += this.action_response.decode(input);
            return codeLength;
        }else if (this.choice == Choice.SECURITY_RESPONSE) {
            this.security_response = new Security_Response();
            codeLength += this.security_response.decode(input);
            return codeLength;
        }else if (this.choice == Choice.CONNECT_RESPONSE) {
            this.connect_response = new Connect_Response();
            codeLength += this.connect_response.decode(input);
            return codeLength;
        }else if (this.choice == Choice.PROXY_RESPONSE) {
            this.proxy_response = new Proxy_Response();
            codeLength += this.proxy_response.decode(input);
            return codeLength;
        }
        throw new Error("Error decoding AxdrChoice: Identifier matched to no item.");

    }

    encode(output: ReverseByteArrayOutputStream): number {
        if (this.dataCode != null) {
            for (let i = this.dataCode.length - 1; i >= 0; i--) {
                output.write(this.dataCode[i]);
            }
            return this.dataCode.length;
        }
        if (this.choice == Choice._ERR_NONE_SELECTED) {
            throw new Error("Error encoding AxdrChoice: No item in choice was selected.");
        }
        let codeLength = 0;
        if (this.choice == Choice.GET_REQUEST) {
            if (this.get_request != null) {
                codeLength += this.get_request.encode(output);
                let c = new AxdrEnum();
                c.set_min_max_val(5);
                codeLength += c.encode(output);
                return codeLength;
            } else {
                throw new Error("get_request is null");
            }

        }else if(this.choice == Choice.SET_REQUEST){
            if (this.set_request != null) {
                codeLength += this.set_request.encode(output);
                let c = new AxdrEnum();
                c.set_min_max_val(6);
                codeLength += c.encode(output);
                return codeLength;
            } else {
                throw new Error("set_request is null");
            }
        }else if (this.choice == Choice.ACTION_REQUEST) {
            if(this.action_request != null){
                codeLength += this.action_request.encode(output);
                let c = new AxdrEnum();
                c.set_min_max_val(7);
                codeLength += c.encode(output);
                return codeLength;
            }else{
                throw new Error("action_request is null");
            }
        }else if (this.choice == Choice.SECURITY_REQUEST) {
            if(this.security_request != null){
                codeLength += this.security_request.encode(output);
                let c = new AxdrEnum();
                c.set_min_max_val(16);
                codeLength += c.encode(output);
                return codeLength;
            }else{
                throw new Error("security_request is null");
            }
        }else if(this.choice == Choice.CONNECT_REQUEST){
            if(this.connect_request != null){
                codeLength += this.connect_request.encode(output);
                let c = new AxdrEnum();
                c.set_min_max_val(2);
                codeLength += c.encode(output);
                return codeLength;
            }else{
                throw new Error("connect_request is null");
            }
        }else if(this.choice == Choice.PROXY_REQUEST){
            if(this.proxy_request != null){
                codeLength += this.proxy_request.encode(output);
                let c = new AxdrEnum();
                c.set_min_max_val(9)
                codeLength += c.encode(output);
                return codeLength;
            }else{
                throw new Error("proxy_request is null");
            }
        }else if (this.choice == Choice.GET_RESPONSE) {
            if(this.get_response != null){
                codeLength += this.get_response.encode(output);
                let c = new AxdrEnum();
                c.set_min_max_val(133);
                codeLength += c.encode(output);
                return codeLength;
            }else{
                throw new Error("get_response is null");
            }
        }else if (this.choice == Choice.SET_RESPONSE) {
            if(this.set_response != null){
                codeLength += this.set_response.encode(output);
                let c = new AxdrEnum();
                c.set_min_max_val(134);
                codeLength += c.encode(output);
                return codeLength;
            }else{
                throw new Error("set_response is null");
            }
        }else if (this.choice == Choice.ACTION_RESPONSE) {
            if(this.action_response != null){
                codeLength += this.action_response.encode(output);
                let c = new AxdrEnum();
                c.set_min_max_val(135);
                codeLength += c.encode(output);
                return codeLength;
            }else{
                throw new Error("action_response is null");
            }
        }else if (this.choice == Choice.SECURITY_RESPONSE) {
            if(this.security_response != null){
                codeLength += this.security_response.encode(output);
                let c = new AxdrEnum();
                c.set_min_max_val(144);
                codeLength += c.encode(output);
                return codeLength;
            }else{
                throw new Error("security_response is null");
            }
        }else if (this.choice == Choice.CONNECT_RESPONSE) {
            if(this.connect_response != null){
                codeLength += this.connect_response.encode(output);
                let c = new AxdrEnum();
                c.set_min_max_val(130);
                codeLength += c.encode(output);
                return codeLength;
            }else{
                throw new Error("connect_response is null");
            }
        }else if (this.choice == Choice.PROXY_RESPONSE) {
            if(this.proxy_response != null){
                codeLength += this.proxy_response.encode(output);
                let c = new AxdrEnum();
                c.set_min_max_val(137);
                codeLength += c.encode(output);
                return codeLength;
            }else{
                throw new Error("proxy_response is null");
            }
        }
        throw new Error("Error encoding AxdrChoice: No item in choice was encoded.");
    }

    setGet_Request(newVal: Get_Request) {
        this.resetChoices();
        this.choice = Choice.GET_REQUEST;
        this.get_request = newVal;
    }

    setSet_Request(newVal: Set_Request){
        this.resetChoices();
        this.choice = Choice.SET_REQUEST;
        this.set_request = newVal;
    }

    setAction_Request(newVal: Action_Request){
        this.resetChoices();
        this.choice = Choice.ACTION_REQUEST;
        this.action_request = newVal;
    }

    setSecurity_Request(newVal: Security_Request){
        this.resetChoices();
        this.choice = Choice.SECURITY_REQUEST;
        this.security_request = newVal;
    }

    setConnect_Request(newVal: Connect_Request){
        this.resetChoices();
        this.choice = Choice.CONNECT_REQUEST;
        this.connect_request = newVal;
    }

    setProxy_Request(newVal: Proxy_Request){
        this.resetChoices();
        this.choice = Choice.PROXY_REQUEST;
        this.proxy_request = newVal;
    }

    setGet_Response(newVal : Get_Response){
        this.resetChoices();
        this.choice = Choice.GET_RESPONSE;
        this.get_response = newVal;
    }

    setSet_Response(newVal : Set_Response){
        this.resetChoices();
        this.choice = Choice.SET_RESPONSE;
        this.set_response = newVal;
    }

    setAction_Response(newVal : Action_Response){
        this.resetChoices();
        this.choice = Choice.SET_RESPONSE;
        this.action_response = newVal;
    }

    setSecurity_Response(newVal : Security_Response){
        this.resetChoices();
        this.choice = Choice.SECURITY_RESPONSE;
        this.security_response = newVal;
    }

    setProxy_Response(newVal : Proxy_Response){
        this.resetChoices();
        this.choice = Choice.PROXY_RESPONSE;
        this.proxy_response = newVal;
    }

    setConnect_Response(newVal : Connect_Response){
        this.resetChoices();
        this.choice = Choice.CONNECT_RESPONSE;
        this.connect_response = newVal;
    }

    getChoiceIndex(): Choice {
        return this.choice;
    }

    resetChoices() {
        this.choice = Choice._ERR_NONE_SELECTED;
        this.get_request = null;
        this.set_request = null;
        this.action_request = null;
        this.security_request = null;
        this.connect_request = null;
        this.proxy_request = null;
        this.get_response = null;
        this.set_response = null;
        this.action_response = null;
        this.security_response = null;
        this.connect_response = null;
        this.proxy_response = null;
    }

    toString(): string {
        if (this.choice == Choice.GET_REQUEST) {
            if (this.get_request != null) {
                return "choice: {get_Request: " + this.get_request + "}";
            } else {
                return "choice is get_request but get_request is null";
            }
        } else if (this.choice == Choice.SET_REQUEST) {
            if (this.set_request != null) {
                return "choice: {set_request: " + this.set_request + "}";
            } else {
                return "choice is set_request but set_request is null";
            }
        } else if (this.choice == Choice.ACTION_REQUEST) {
            if (this.action_request != null) {
                return "choice: {action_request: " + this.action_request + "}";
            } else {
                return "choice is action_request but action_request is null";
            }
        }else if (this.choice == Choice.SECURITY_REQUEST) {
            if (this.security_request != null) {
                return "choice: {security_request: " + this.security_request + "}";
            } else {
                return "choice is security_request but security_request is null";
            }
        }else if(this.choice == Choice.CONNECT_REQUEST){
            if (this.connect_request != null) {
                return "choice: {connect_request: " + this.connect_request + "}";
            } else {
                return "choice is connect_request but connect_request is null";
            }
        } else if(this.choice == Choice.PROXY_REQUEST){
            if (this.proxy_request != null) {
                return "choice: {proxy_request: " + this.proxy_request + "}";
            } else {
                return "choice is proxy_request but proxy_request is null";
            }
        } else if (this.choice == Choice.GET_RESPONSE) {
            if (this.get_response != null) {
                return "choice: {get_response: " + this.get_response + "}";
            } else {
                return "choice is get_response but get_response is null";
            }
        } else if (this.choice == Choice.SET_RESPONSE) {
            if (this.set_response != null) {
                return "choice: {set_response: " + this.set_response + "}";
            } else {
                return "choice is set_response but set_response is null";
            }
        }else if (this.choice == Choice.ACTION_RESPONSE) {
            if (this.action_response != null) {
                return "choice: {action_response: " + this.action_response + "}";
            } else {
                return "choice is action_response but action_response is null";
            }
        }else if(this.choice == Choice.CONNECT_RESPONSE){
            if (this.connect_response != null) {
                return "choice: {connect_response: " + this.connect_response + "}";
            } else {
                return "choice is connect_response but connect_response is null";
            }
        } else if(this.choice == Choice.PROXY_RESPONSE){
            if (this.proxy_response != null) {
                return "choice: {proxy_response: " + this.proxy_response + "}";
            } else {
                return "choice is proxy_response but proxy_response is null";
            }
        } else if(this.choice == Choice.SECURITY_RESPONSE){
            if (this.security_response != null) {
                return "choice: {security_response: " + this.security_response + "}";
            } else {
                return "choice is security_response but security_response is null";
            }
        } else {
            return "";
        }
    }

}
